/***********************************************************************************************************************
*  OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
*  See also https://openstudio.net/license
***********************************************************************************************************************/

#ifndef AIRFLOW_SURFACENETWORKBUILDER_HPP
#define AIRFLOW_SURFACENETWORKBUILDER_HPP

#include <vector>

#include "AirflowAPI.hpp"

#include "../utilities/core/Logger.hpp"
#include "../utilities/core/StringStreamLogSink.hpp"

namespace openstudio {

class ProgressBar;
namespace model {
  class Model;
  class Space;
  class ThermalZone;
  class SubSurface;
  class Surface;
}  // namespace model

namespace airflow {

  /** SurfaceNetworkBuilder objects walk the OpenStudio model as a network of surfaces.
 *
 *  The SurfaceNetworkBuilder object walks the OpenStudio model as a network of surface,
 *  calling a different function once for each pair of interior surfaces or subsurfaces and
 *  once for each exterior surface or subsurface. The intended usage is to subclass for a
 *  specific application.
 *
 */
  class AIRFLOW_API SurfaceNetworkBuilder
  {
   public:
    /** @name Constructors and Destructors */
    //@{
    /** Construct a new object. */
    explicit SurfaceNetworkBuilder(ProgressBar* progressBar = nullptr);
    /** Destroy the translator.*/
    virtual ~SurfaceNetworkBuilder() = default;

    //@}
    /** @name Network Construction Functions */
    //@{

    bool build(model::Model& model);

    //@}
    /** @name Getters and Setters */
    //@{

    /** Returns the progress bar currently associated with the object. */
    ProgressBar* progressBar() const;

    /** Sets the progress bar to be updated by the object. */
    void setProgressBar(ProgressBar* progressBar);

    //@}
    /** @name Miscellaneous Functions */
    //@{

    /** Clear any internally stored information in the builder object. */
    virtual void clear() {}

    /** Returns warning messages generated by the last translation. */
    std::vector<LogMessage> warnings() const;

    /** Returns error messages generated by the last translation. */
    std::vector<LogMessage> errors() const;

    /** Returns error messages generated by the last translation. */
    std::vector<LogMessage> logMessages() const;

    //@}

   protected:
    void progress();
    void initProgress(int max, std::string label);

    virtual bool linkExteriorSurface(model::ThermalZone zone, model::Space space, model::Surface surface);
    virtual bool linkExteriorSubSurface(model::ThermalZone zone, model::Space space, model::Surface surface, model::SubSurface subSurface);
    virtual bool linkInteriorSurface(model::ThermalZone zone, model::Space space, model::Surface surface, model::Surface adjacentSurface,
                                     model::Space adjacentSpace, model::ThermalZone adjacentZone);
    virtual bool linkInteriorSubSurface(model::ThermalZone zone, model::Space space, model::Surface surface, model::SubSurface subSurface,
                                        model::SubSurface adjacentSubSurface, model::Surface adjacentSurface, model::Space adjacentSpace,
                                        model::ThermalZone adjacentZone);

   private:
    ProgressBar* m_progressBar;
    StringStreamLogSink m_logSink;

    REGISTER_LOGGER("openstudio.airflow.SurfaceNetworkBuilder");
  };

}  // namespace airflow
}  // namespace openstudio

#endif  // AIRFLOW_SURFACENETWORKBUILDER_HPP
